package com.scientific.research.gobang.service.match.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.scientific.research.gobang.mapper.MatchMapper;
import com.scientific.research.gobang.mapper.SignMessageMapper;
import com.scientific.research.gobang.pojo.MatchMessage;
import com.scientific.research.gobang.pojo.SignMessage;
import com.scientific.research.gobang.pojo.User;
import com.scientific.research.gobang.service.MatchCodeRunService;
import com.scientific.research.gobang.service.MatchService;
import com.scientific.research.gobang.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class MatchServiceImpl implements MatchService {
    @Autowired
    MatchMapper matchMapper;
    @Autowired
    MatchCodeRunService matchCodeRunService;
    @Autowired
    SignMessageMapper signMessageMapper;
    @Autowired
    UserService userService;

    //Update已经报名截止的比赛
    @Override
    public void matchDataPass(String soon) {
        int matchId = Integer.valueOf(soon);
        MatchMessage match = new MatchMessage();
        match.setId(matchId);
        match.setResult("报名截止");
        matchMapper.updateById(match);
    }

    //修改报名持续时间，前端规定修改后的时间是从现在起3天以上
    @Override
    public void changeMatchEndTime(MatchMessage match) {
        match.setResult("正在报名");
        matchMapper.updateById(match);
    }

    //用户想修改参赛代码时，先调用此方法获取这个用户的比赛相关信息（如邮箱，比赛场次，已提交代码等）
    @Override
    public SignMessage getUserMatchCode(Map postData) {
        Map userToken = (Map) postData.get("userToken");
        int matchId = (Integer) postData.get("soon");
        User user = userService.LodeUserMessage(userToken);
        SignMessage signMessage = new SignMessage();
        signMessage.setMatchId(matchId);
        signMessage.setUserEmail(user.getEmail());

        HashMap<String, Object> selectCondition = new HashMap<>();
        selectCondition.put("match_id", signMessage.getMatchId());
        selectCondition.put("user_email", signMessage.getUserEmail());
        signMessage = signMessageMapper.selectByMap(selectCondition).get(0);
        return signMessage;
    }

    //用户提交参赛代码。将提交的代码、选择的语言更新到对应的signMessage表中
    @Override
    public void userSubmitCode(Map signMessage) {
        User user = userService.LodeUserMessage(signMessage);
        SignMessage signMessagePut = new SignMessage();
        signMessagePut.setUserEmail(user.getEmail());
        signMessagePut.setMatchId(Integer.valueOf((String) signMessage.get("matchId")));
        signMessagePut.setCode((String) signMessage.get("code"));
        signMessagePut.setLanguage((String) signMessage.get("language"));
        QueryWrapper<SignMessage> wrapper = new QueryWrapper<>();
        wrapper
                .eq("user_email", signMessagePut.getUserEmail())
                .eq("match_id", signMessagePut.getMatchId());
        signMessageMapper.update(signMessagePut, wrapper);
    }

    //用户报名参加比赛，将用户信息写入signMessageMapper表中，并且matchMapper表中的报名人数+1
    @Override
    public String insertMatchUser(Map map) {
        String result;
        int matchId = Integer.valueOf((String) map.get("data"));
        User user = userService.LodeUserMessage(map);
        MatchMessage match = matchMapper.selectById(matchId);
        //如果已报名的人数没有满，就可以报名
        if (match.getNowNumber() < match.getUserNumber()) {
            SignMessage signMessage = new SignMessage();
            signMessage.setUserEmail(user.getEmail());
            signMessage.setMatchId(matchId);
            QueryWrapper<SignMessage> wrapper = new QueryWrapper<>();
            wrapper
                    .eq("user_email", signMessage.getUserEmail())
                    .eq("match_id", matchId);
            SignMessage soon = signMessageMapper.selectOne(wrapper);
            if (soon == null) {//查询结果为null说明用户还没报名，那么报名成功
                signMessageMapper.insert(signMessage);
                match.setNowNumber(match.getNowNumber() + 1);
                matchMapper.updateById(match);
                result = "success";
            } else { //否则返回exist，代表用户已经报名
                result = "exist";
            }
        } //fail代表报名人数已满
        else {
            MatchMessage matchTwo = new MatchMessage();
            matchTwo.setId(matchId);
            matchTwo.setResult("报名结束");
            matchMapper.updateById(match);
            result = "fail";
        }
        return result;
    }

    //管理员创建一场比赛，保存比赛信息
    @Override
    public void saveMatchMessage(Map map) {
        MatchMessage match = new MatchMessage();
        User user = userService.LodeUserMessage(map);
        match.setCreateUser(user.getEmail());//设置创建这场比赛的管理员信息
        match.setResult("正在报名");//设置比赛的各种信息
        match.setTitle((String) map.get("title"));
        match.setUserNumber((Integer) map.get("userNumber"));
        match.setType((String) map.get("type"));
        match.setEndTime((String) map.get("endTime"));
        match.setMatchDescribe((String) map.get("describe"));
        match.setCreateTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));//设置创建这场比赛时的日期，取系统当前时间
        matchMapper.insert(match);
    }

    //用户查看当前所有比赛信息的界面，返回前20场比赛的相关信息（如正在报名，报名结束，已完成的各场比赛）
    @Override
    public List<MatchMessage> toUserMatch(Map map) {
        User user = userService.LodeUserMessage(map);
        Page<MatchMessage> pages = new Page<>(1, 20);
        matchMapper.selectPage(pages, null);
        List<MatchMessage> matchList = pages.getRecords();
        int jurge = 0;
        for (int i = 0; i < matchList.size(); i++) {

            if (!"已完成".equals(matchList.get(i).getResult()) && matchList.get(i).getNowNumber() == matchList.get(i).getUserNumber()) {
                MatchMessage matchTwo = new MatchMessage();
                matchTwo.setId(matchList.get(i).getId());
                matchTwo.setResult("报名结束");
                matchMapper.updateById(matchTwo);
                matchList.get(i).setResult("报名结束");
            }

            if (!"已完成".equals(matchList.get(i).getResult()) && !"正在进行".equals(matchList.get(i).getResult())) {
                HashMap<String, Object> selectMatchId = new HashMap<>();
                selectMatchId.put("match_id", matchList.get(i).getId());
                List<SignMessage> userList = signMessageMapper.selectByMap(selectMatchId);
                jurge = 0;
                for (SignMessage signMessage : userList) {
                    if (signMessage.getUserEmail().equals(user.getEmail()) && signMessage.getCode() == null) {
                        String soonStr = matchList.get(i).getTitle();
                        soonStr += "##codeNull##";
                        matchList.get(i).setTitle(soonStr);
                        break;
                    } else if (signMessage.getUserEmail().equals(user.getEmail())) {
                        jurge = 1;
                        break;
                    }
                }
                if (jurge == 0) {
                    String soonStr = matchList.get(i).getTitle();
                    soonStr += "##userNull##";
                    matchList.get(i).setTitle(soonStr);
                }
            }
        }
        return matchList;
    }

    //比赛结束后，获取第i场比赛的信息，如获胜选手等信息
    @Override
    public MatchMessage toMatchResult(String id) {
        int matchId = Integer.valueOf(id);
        MatchMessage match = matchMapper.selectById(matchId);
        String soon = match.getCodeResult();
        soon = soon.replaceAll("[-\\s]", "");
        soon = soon.replaceAll(":", "");
        match.setCodeResult(soon);
        return match;
    }

    //开始比赛，比赛选手的代码进行编译、运行后得出优胜者
    @Override
    public void startMatch(String soon) {
        int matchId = Integer.valueOf(soon);
        MatchMessage match = matchMapper.selectById(matchId);
        match.setResult("正在进行");
        matchMapper.updateById(match);
        matchCodeRunService.RunOneMatch(matchId);
    }

}
